package server.model.auctionModel;

import org.apache.commons.dbutils.handlers.BeanHandler;
import server.db.DBDriver;
import server.db.DBFactory;
import server.entity.Auction;
import server.entity.Good;
import server.model.factory.ModelFactory;
import server.util.DBUtils;
import server.util.InfoUtils.Info;
import server.util.InfoUtils.InfoEnum;
import server.util.InfoUtils.InfoUtil;
import server.util.MyUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

public class AuctionModel {
    //新建拍卖
    public Info addAuction(Auction auction) {
        String sql = "insert into auction (good_id,start,end,max_price) values (?,?,?,?)";

        //判空
        if (!MyUtils.NOTNULL(auction.getGoodId(), auction.getStart(), auction.getEnd(), auction.getMaxPrice())) {
            return InfoUtil.getInfo(InfoEnum.PARAMS_NULL);
        }

        //判断终止时间是否大于当前时间
        Date endDate = auction.getEnd();
        if (endDate.compareTo(new Date()) <= 0) {
            return InfoUtil.getInfo(1, "终止时间必须大于当前时间");
        }

        ArrayList<Object> params = new ArrayList<>();
        params.add(auction.getGoodId());
        params.add(auction.getStart());
        params.add(auction.getEnd());
        params.add(auction.getMaxPrice());

        if (DBFactory.getDBDriver().update(sql, params.toArray()) <= 0) {
            return InfoUtil.getInfo(InfoEnum.FAIL);//处理错误
        }

        //获取新插入的拍卖Id
        Integer auctionId = DBUtils.getInsertId("auction_id");
        if (auctionId == 0) return InfoUtil.getInfo(InfoEnum.FAIL);//处理错误

        //设置good的auction_id
        Good good = new Good();
        good.setGoodId(auction.getGoodId());
        good.setAuctionId(auctionId);
        if (ModelFactory.getGoodInfoModel().setGoodInfo(good).getCode() != 0) {
            return InfoUtil.getInfo(InfoEnum.FAIL);//处理错误
        }

        //开启线程，检测终止的时间
        endToDo(auction.getEnd(), auctionId);

        return InfoUtil.getInfo(InfoEnum.SUCCESS);
    }

    //通过auctionId查询拍卖信息
    public Info getAuction(Integer auctionId) {
        String sql = "select * from auction where auction_id = ?";
        Auction auction = DBFactory.getDBDriver().query(sql, new BeanHandler<>(Auction.class, DBDriver.getProcess()), auctionId);
        if (auction == null) {
            return InfoUtil.getInfo(InfoEnum.FAIL);
        }
        return InfoUtil.getInfo(auction);
    }

    //竞拍
    public Info bid(Auction bidder) {
        if (!MyUtils.NOTNULL(bidder.getMaxPrice(), bidder.getAuctionId(), bidder.getUserId())) {
            return InfoUtil.getInfo(InfoEnum.PARAMS_NULL);
        }

        //获取数据库中的拍卖信息
        Info info = getAuction(bidder.getAuctionId());
        if (info.getCode() != 0) {
            return InfoUtil.getInfo(InfoEnum.FAIL);
        }
        Auction auction = (Auction) info.getData();

        //判断时间
        if (new Date().compareTo(auction.getStart()) < 0) {
            return InfoUtil.getInfo(1, "拍卖还未开始");
        }
        if (new Date().compareTo(auction.getEnd()) > 0) {
            return InfoUtil.getInfo(2, "拍卖已经结束");
        }

        //判断出价
        if (bidder.getMaxPrice() <= auction.getMaxPrice()) {
            return InfoUtil.getInfo(3, "您的竞拍出价必须高于现有最高价格");
        }

        //更新拍卖的信息
        if (bidSetAuction(bidder.getAuctionId(), bidder.getUserId(), bidder.getMaxPrice()).getCode() != 0) {
            return InfoUtil.getInfo(InfoEnum.FAIL);
        }
        return InfoUtil.getInfo(InfoEnum.SUCCESS);
    }

    public Info bidSetAuction(Integer auctionId, Integer userId, Double price) {
        String sql = "update auction set max_price = ? , user_id = ? where auction_id = ?";
        if (DBFactory.getDBDriver().update(sql, price, userId, auctionId) <= 0) {
            return InfoUtil.getInfo(InfoEnum.FAIL);
        }
        return InfoUtil.getInfo(InfoEnum.SUCCESS);
    }

    public Info deleteAuction(int auctionId) {
        //设置good数据表中的auction为0
        String sql = "update good set auction_id = 0 where auction_id = ?";
        if (DBFactory.getDBDriver().update(sql, auctionId) <= 0) {
            return InfoUtil.getInfo(InfoEnum.FAIL);
        }

        return InfoUtil.getInfo(InfoEnum.SUCCESS);
    }

    //拍卖时间截止
    public void endToDo(Date endDate, Integer auctionId) {
        Timer timer = new Timer();
        System.out.println("timer begin..");
        timer.schedule(new TimerTask() {
            @Override
            public void run() {
                Info auctionInfo = getAuction(auctionId);
                if (auctionInfo.getCode() == 0) {
                    Auction auction = (Auction) auctionInfo.getData();
                    if (auction.getUserId() != null) {
                        System.out.println("execute...");
                        ModelFactory.getGoodModel().auctionPurchase(auction.getUserId(), auction.getGoodId(),auction.getMaxPrice());
                    }
                    deleteAuction(auctionId);
                    System.out.println("delete..");
                }
                timer.cancel();
            }
        }, endDate);
    }

}
